package exceptions;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * @author 26029
 * @date 2025/4/8
 * @description
 */
public class LearnException {
    public static void main(String[] args){
        // Throwable -> Error & Exception
        // 1. Error 类及其子类：
        // 程序中无法处理的错误，表示运行应用程序中出现了严重的错误。此类错误一般表示代码运行时 JVM 出现问题。
        // 是不受检异常，意味着无需手动处理。
        try {
            throw new Error("test error");
        } catch (Error e) {
            System.out.println(e.getMessage());
        }
        // 2. Exception：
        // 分为 运行时异常 和 非运行时异常（编译异常）
        // 运行时异常一般是由程序逻辑错误引起的，可以不处理，是不受检异常
        try {
            throw new RuntimeException("test runtime exception");
        } catch (RuntimeException e) {
            System.out.println(e.getMessage());
        }
        // 非运行时异常是受检异常，必须try-catch处理或向上抛出
        try {
            throw new IOException("test io exception");
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }

        // try-catch-finally中，finally遇见如下情况不会执行:
        // 在前面的代码中用了System.exit()退出程序。
        // finally语句块中发生了异常。
        // 程序所在的线程死亡。
        // 关闭CPU。
        try {
            System.out.println("1");
            throw new Exception("test finally");
        } catch (Exception e) {
            System.out.println(e.getMessage());
            // 退出程序，使finally不执行
            // System.exit(0);
        } finally {
            System.out.println("3");
        }

        // try-with-resource 保证try出现异常时，在try中把资源释放掉，防止在finally中释放再出现异常，代码也很丑
        // 资源必须实现 AutoCloseable 或 Closable 接口
        try (Scanner scanner = new Scanner(new FileInputStream("c:/abc"), StandardCharsets.UTF_8)){
            // Scanner实现了Closable接口
            System.out.println("尝试连接...");
        } catch (IOException e){
            // handle exception
            System.out.println(e.getMessage());
        }

        // finally中不要返回
        LearnException le = new LearnException();
        System.out.println(le.checkReturn());
    }

    public int checkReturn() {
        try {
            // x等于1，此处不返回
            return 1;
        } finally {
            // 返回的结果是2
            return 2;
        }
    }
}
